package ltd.hxya.novel.common.exception;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import ltd.hxya.novel.common.bean.Result;
import ltd.hxya.novel.common.bean.ResultEnum;
import ltd.hxya.novel.common.valid.ValidBeanException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.ArrayList;
import java.util.List;

/**
 * 全局异常处理类，处理在程序中出现的异常，并在NovelGlobalException中自定义全局异常类
 */
@Slf4j
@RestControllerAdvice
public class NovelGlobalExceptionHandler {

    @ExceptionHandler(NovelGlobalException.class)
    public Result novelGlobalException(NovelGlobalException globalException){
        log.error("异常：",globalException);
        Result<Void> failResult = Result.fail(globalException.getCode(), globalException.getMessage());
        return failResult;
    }

    //BindException只对使用表单方式提交的参数有效
    @ExceptionHandler( BindException.class)
    public Result bindException(BindException bindException){
        List<ValidBeanException> validBeanExceptions = handlerValidException(bindException, null);

        return Result.fail(ResultEnum.PARAM_VALID_FAIL.getCode(), validBeanExceptions);
    }

    public List<ValidBeanException> handlerValidException(BindException bindException,MethodArgumentNotValidException validException){
        BindingResult bindingResult =null;
        if (bindException==null&&validException!=null){
            bindingResult = validException.getBindingResult();
        }
        if (bindException!=null&&validException==null){
            bindingResult = bindException.getBindingResult();
        }
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        List<ValidBeanException> validBeanExceptions = new ArrayList<>();
        fieldErrors.stream().forEach(fieldError -> {
            String defaultMessage = fieldError.getDefaultMessage();
            String field = fieldError.getField();
            ValidBeanException validBeanException = new ValidBeanException();
            validBeanException.setFieldName(field);
            validBeanException.setMessage(defaultMessage);
            validBeanExceptions.add(validBeanException);
        });

        return validBeanExceptions;

    }

    //MethodArgumentNotValidException只对传递的json格式的参数有效
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result methodArgumentNotValidException(MethodArgumentNotValidException validException){
        List<ValidBeanException> validBeanExceptions = handlerValidException(null, validException);
        return Result.fail(ResultEnum.PARAM_VALID_FAIL.getCode(), validBeanExceptions);
    }


    @ExceptionHandler(Exception.class)
    public Result unKnownException(Exception exception){
        log.error("异常：",exception);
        Result<Void> failResult = Result.fail(ResultEnum.UN_KNOWN_EXCEPTION.getCode() ,ResultEnum.UN_KNOWN_EXCEPTION.getMsg());

        return failResult;
    }
}
